﻿/********************************************************************************/
/* 	effectt.d																	*/
/*------------------------------------------------------------------------------*/
/*	製作		（　゜ワ゜）ノ　／　松久貫太									*/
/*	製作開始　	2007/05/11														*/
/*	MAIL		omega@personal.email.ne.jp										*/
/*	URL		http://nagoya.cool.ne.jp/o_mega										*/
/*																				*/
/*	このソースは「やらわかライセンス」の元で配布されています。					*/
/*-更新履歴---------------------------------------------------------------------*/
/*	2007/--/--																	*/
/*-その他-----------------------------------------------------------------------*/
/*	なし																		*/
/********************************************************************************/

private import hell2;
private import actor;
private import vector;
private import screen;
private import std.math;

private import defines;


// 種類
enum EFFECTTYPE
{
	TRIANGLE,
	LINE,
	POINT,
};


class EffectActor : ActorPool!(Effect)
{
	this(int n)
	{
		super(n);
	}
	
	void add(Vec3 p ,Vec3 v,EFFECTTYPE type)
	{
		Effect e = this.getInstanceForced();
		if(e)
		{
			e.init(p,v,type);
		}
	}
}


//
class Effect : Actor
{
public:
	Vec3 trail;
	Vec3 speed;
	Vec3 rotation;
	Vec3 rot_speed;
	EFFECTTYPE type;
	int timer;
	int dead_time;
	float color[3];
	
	this()
	{
		super();
	}
	
	void init(Vec3 p,Vec3 v,EFFECTTYPE type)
	{
		position = new Vec3(p);
		rotation = new Vec3();
		speed = new Vec3(v);
		exist = true;
		this.type = type;
		timer = 0;
		
		switch(type)
		{
			case EFFECTTYPE.TRIANGLE:
				dead_time = Hell_randInt(60,240);
				float sp = Hell_randInt(0,100) / 400.0;
				float r1 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				float r2 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				speed = new Vec3( sp * cos(r1) * sin(r2) ,
								sp * sin(r1) * sin(r2) ,
								sp * cos(r2) );
				rot_speed = new Vec3( Hell_randInt(-100,100) / 4.0 ,
								Hell_randInt(-100,100) / 4.0 ,
								Hell_randInt(-100,100) / 4.0 );
				color[0] = 1.0;
				color[1] = 0.4;
				color[2] = 0.1;
				break;
			
			case EFFECTTYPE.LINE:
				dead_time = Hell_randInt(30,90);
				float sp = Hell_randInt(0,100) * Hell_randInt(0,100) / 80000.0;
				float r1 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				float r2 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				speed = new Vec3( sp * cos(r1) * sin(r2) ,
								sp * sin(r1) * sin(r2) ,
								sp * cos(r2) );
				trail = new Vec3(position);
				position += (speed * cast(float)dead_time);
				color[0] = Hell_randInt(-200,0) / 1000.0 + 1.0;
				color[1] = Hell_randInt(-200,0) / 1000.0 + 0.4;
				color[2] = Hell_randInt(-200,0) / 1000.0 + 0.4;
				break;
			
			case EFFECTTYPE.POINT:
				dead_time = Hell_randInt(60,90);
				/*
				float sp = Hell_randInt(0,100) * Hell_randInt(0,100) / 4000.0;
				float r1 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				float r2 = Hell_randInt(-100,100) / 100.0 * 3.141592;
				speed = new Vec3( sp * cos(r1) * sin(r2) ,
								sp * sin(r1) * sin(r2) ,
								sp * cos(r2) );*/
				trail = new Vec3(position);
				color[0] = 1.0;
				color[1] = 0.4;
				color[2] = 0.1;
				break;
			
			default:
				break;
		}
	}
	
	void move()
	{
		timer++;
		if(timer > dead_time)
			{
				exist = false;
		}
		
		if(position.z < CHAR_Z_SURFACE && speed.z < 0){
			speed.z *= -0.9;
			position.z = CHAR_Z_SURFACE;
		}
		speed.z -= 0.005;
		
		switch(type)
		{
			case EFFECTTYPE.TRIANGLE:
				position += speed;
				//position.z -= 0.1;
				rotation += rot_speed;
				if(timer % 2 == 0 && Hell_randInt(0,10) < 7)
				{
				//	speed *= 0.95;
					rot_speed *= 0.95;
				}
				break;
			
			case EFFECTTYPE.LINE:
				trail = 0.9 * trail + 0.1 * position;
				position += speed;
				//speed *= 0.99;
				break;
			
			case EFFECTTYPE.POINT:
				trail = 0.5 * trail + 0.5 * position;
				position += speed;
				//position.z -= 0.1;
				speed *= 0.95;
				break;
			default:
				break;
		}
	}
	
	void draw()
	{
		float alpha = (cast(float)(dead_time - timer)) / dead_time * 2.0;
		if(alpha > 1.0)
		{
			alpha = 1.0;
		}
		
		glPushMatrix();
		switch(type)
		{
			case EFFECTTYPE.TRIANGLE:
				glTranslatef(position.x , position.y , position.z);
				glRotatef(rotation.x , rotation.y , rotation.z);
				
				glScalef(0.5 , 0.5 , 0.5);
				
				glColor4f(color[0] , color[1] , color[2] , alpha * 0.3);
				TriangleShape.drawPolygon();
				glColor4f(color[0] , color[1] , color[2] , alpha * 0.8);
				TriangleShape.drawWire();
				break;
			
			case EFFECTTYPE.LINE:
				glColor4f(color[0] , color[1] , color[2] , alpha * 0.9);
				LineShape.drawWire(position , trail);
				break;
			case EFFECTTYPE.POINT:
				glColor4f(color[0] , color[1] , color[2] , alpha * 0.8);
				LineShape.drawWireFade(position , trail);
				break;
			
			default:
				break;
		}
		glPopMatrix();
	}
}

//--------------------------------------------------------------------

class PerticleActor : ActorPool!(Perticle)
{
	this(int n)
	{
		super(n);
	}
	
	void draw()
	{
		LineShape.drawWireLinesBegin();	// 一括Begin
		super.draw();
		LineShape.drawWireLinesEnd();
	}
	
	void add(Vec3 p ,Vec3 v,EFFECTTYPE type)
	{
		Perticle e = this.getInstanceForced();
		if(e)
		{
			e.init(p,v,type);
		}
	}
}
/* */
class Perticle : Actor
{
public:
	Vec3 trail;
	Vec3 speed;
	int timer;
	int dead_time;
	float color[3];
	
	this()
	{
		super();
	}
	
	void init(Vec3 p,Vec3 v,EFFECTTYPE type)
	{
		position = new Vec3(p);
		speed = new Vec3(v);
		exist = true;
		timer = 0;
		
		dead_time = Hell_randInt(60,90);
		/*
		float sp = Hell_randInt(0,100) * Hell_randInt(0,100) / 4000.0;
		float r1 = Hell_randInt(-100,100) / 100.0 * 3.141592;
		float r2 = Hell_randInt(-100,100) / 100.0 * 3.141592;
		speed = new Vec3( sp * cos(r1) * sin(r2) ,
						sp * sin(r1) * sin(r2) ,
						sp * cos(r2) );*/
		trail = new Vec3(position);
		color[0] = 1.0;
		color[1] = 0.4;
		color[2] = 0.1;
	}
	
	void move()
	{
		timer++;
		if(timer > dead_time)
			{
				exist = false;
		}
		
		if(position.z < CHAR_Z_SURFACE && speed.z < 0){
			speed.z *= -0.9;
			position.z = CHAR_Z_SURFACE;
		}
		speed.z -= 0.005;
		
		trail = 0.5 * trail + 0.5 * position;
		position += speed;
		speed *= 0.95;
	}
	
	void draw()
	{
		float alpha = (cast(float)(dead_time - timer)) / dead_time * 2.0;
		if(alpha > 1.0)
		{
			alpha = 1.0;
		}
		
		glColor4f(color[0] , color[1] , color[2] , alpha * 0.8);
		LineShape.drawWireLines(position , trail);	// 連続作画
	}
}